#+TITLE: Emacs Lisp Cheat Sheet
#+AUTHOR: Joshua Branson
# make sure that we can see the text
#+LATEX_HEADER: \usepackage{lmodern}
#+LATEX_HEADER: \usepackage[QX]{fontenc}

* Introduction

Guile is a scheme based lisp that is intended to be the universal GNU extension language.  It is designed to inter-operate with C code very easily (though I wish it could do the same with Rust code), and it supports programming in other languages (javascript, emacs-lisp, and hopefully someday many others).  Guile has a module based system, threads, full access to POSIX calls, dynamic linking, networking support, string processing, a foreign function call interface (let's Guile run a function from a different language), etc.

When emacs-lisp became so popular in extending Emacs, some of the leaders of the GNU project, wanted to make an official lisp language that all others GNU packages could use as an extension language.  Currently only a few Emacs packages use Guile as an extension language, but hopefully someday many more will.  In fact, perhaps in a few years, the default Emacs package will probably run on the Guile vm (running emacs lisp code), which will make the default Emacs experience that much faster!

* Learning Some Scheme
** Absolute Basic of Scheme

Scheme, like most lisps, has a very limited syntax.  This is actually a valuable language feature, because it makes the language easy to learn.  The two main things to learn are the following:

- ~(operator operand1 operand2 operand3 ...)~

  The first word in a parenthesis in guile, is a command.  The following words are arguments to the command.  For example,
  ~(+ 5 3)~ evaluates to 8.  This calculation commands can even be nested in complicated ways like

  #+BEGIN_SRC scheme
    (+ 5 (* 3 (- 8 3 (- 10 9)) (/ 10 2)) (+ 8 9 10))
  #+END_SRC

    which can be rearranged to be so that humans can understand how to compute this odd arbitrary expression.

  #+BEGIN_SRC scheme
    (+ 5
       (* 3
          (- 8 3
             (- 10 9))
          (/ 10 2))
       (+ 8 9 10))
  #+END_SRC

This set up is quite nice.  If you align the operands vertically it gives one a good understanding up what is
happening.

** Scheme is latently typed

Scheme is latent-ly typed.  This is like dynamic typing, which is like python.  A variable does not have to have an associated type with it.  The following python code demonstrates this.  The variable ~a~ can change between a string or a number depending on what is assigned to it.

#+BEGIN_SRC python :results output :export both
a = 5
print (a)
a = "hello"
print (a)
#+END_SRC

#+RESULTS:
: 5
: hello

** Defining variables

 Defining variables in scheme is easy too.

  #+BEGIN_SRC scheme
   (define color blue)
  #+END_SRC

   To change a variable's value, one does

  #+BEGIN_SRC scheme
  (set! x blue)
  #+END_SRC

  In scheme ~#t~ and ~#f~ are the booleans true and false.

  You can also easily define functions
#+BEGIN_SRC scheme
  (define *3 (lambda (x) (* x 3)))
#+END_SRC

You can also write it like:

#+BEGIN_SRC scheme
(define (*3 x) (* x 3))
#+END_SRC

** Going back to our lisp roots

Scheme is a dialect of lisp, which stands for list processing.  A list is just a bunch of linked cons cells.  A cons cell is a constructor that makes lists.  A cons cell contains two element.  The first element is called the car, and the second is called tho cdr (could-er).  These are cons cells.

#+BEGIN_SRC emacs-lisp
(cons 1 2)
#+END_SRC

#+RESULTS:
: (1 . 2)

#+begin_src emacs-lisp :tangle yes
'(1 2)
#+end_src

#+RESULTS:
| 1 | 2 |

#+BEGIN_SRC scheme
  (cons 1 '())
#+END_SRC

#+RESULTS:
: (1)

To make a list, you build up a ton of cons cells:

#+BEGIN_SRC scheme
(cons 5 (cons 2 (cons 6 (cons 1 '()))))
#+END_SRC

#+RESULTS:
: (5 2 6 1)

You can also make a list like this:

#+BEGIN_SRC scheme
'(5 . (2 . (4 . ( 8 . ()))))
#+END_SRC

#+RESULTS:
: (5 2 4 8)

Since scheme processes lists, you can write a plus operation as a list.
#+BEGIN_SRC scheme
(+ . (5 . (2 . ())))
#+END_SRC

#+RESULTS:
: 7

There are also some things that look like procedures, but are actually special syntax.  A good example is the "if" syntax.

#+BEGIN_SRC scheme
  (if (string=? (read-answer "should I copy this file")
                "yes")
      (copy-file "/path/to/file.scm")
      (print "Fine I won't copy the file."))
#+END_SRC

If "if" was a procedure, then copy-file and string=? would be evaluated, then given to if as arguments.  BUT that's not what happens.  Instead, if acts in a different way.  Namely if TEST THEN ELSE.  If TEST returns true, then the THEN is executed.  Otherwise the ELSE is executed.

** Quoting
The first word after the parenthesis is the procedure and the other words are it's arguments.
#+BEGIN_SRC scheme
(+ 2 3)
#+END_SRC

#+RESULTS:
: 5

But you can quote something and it just returns data
#+BEGIN_SRC scheme
'(+ 2 3)
#+END_SRC

#+RESULTS:
: (+ 2 3)

You can also quote things and quasi-quote in the middle.
#+BEGIN_SRC scheme
`(+ 2 ,(* 2 4))
#+END_SRC

#+RESULTS:
: (+ 2 8)

You can also unquote slicing!

#+BEGIN_SRC scheme
(define x '(2 3))
`(1 ,x 4)
#+END_SRC

#+RESULTS:
| 1 | (2 3) | 4 |


#+BEGIN_SRC scheme
(define x '(2 3))
`(1 ,@x 4)
#+END_SRC

#+RESULTS:
| 1 | 2 | 3 | 4 |


#+BEGIN_SRC scheme
(define x '(2 3))
`(1 (+ ,@x) 4)
#+END_SRC

#+RESULTS:
| 1 | (+ 2 3) | 4 |

** Closures

Closures are a bit like static variables in C.  It is a way to make a function being called repeatedly remember the value of the variables instead of resetting them.  ie:

#+BEGIN_SRC scheme
  (let loop ((number 0))
    (lambda ()
      (unless (> number 10)
        (set! number (+ 1 number))
        (display "Number is ")
        (display number)
        (display "\n")
        (loop number))))

#+END_SRC

#+RESULTS:
: #<procedure f09371daf00 at <unknown port>:6:2 ()>

** atoms

This is an atom
#+BEGIN_SRC scheme
atom
#+END_SRC

#+RESULTS:
: (atom)

So is this
#+BEGIN_SRC scheme
stnahuntsuhntahouetnhsn34thu
#+END_SRC

So is this
#+BEGIN_SRC scheme
23435345
#+END_SRC

I'm not an atom, I'm a list
#+BEGIN_SRC scheme
'()
#+END_SRC

#+RESULTS:
: ()

Guile doesn't have the standard scheme procedure to check for atoms: "atom?".  Let's write one!

#+NAME: atom
#+BEGIN_SRC scheme :noweb yes
  (define atom?
    (lambda (a)
      (if (list? a)
          #f
          #t)))
#+END_SRC

** S-expressions

All atoms are S-expressions

This is an S-expression
#+BEGIN_SRC scheme
atom
#+END_SRC

** lists

A list is a set of S expressions enclosed by parenthesis

#+BEGIN_SRC scheme
'(I'm a list)
#+END_SRC

#+RESULTS:
: (I'm a list)

I'm a list
#+BEGIN_SRC scheme
'()
#+END_SRC

** null?
Null returns true if it's parameter is an empty list.

#+BEGIN_SRC scheme
(null? '())
#+END_SRC

#+RESULTS:
: #t

#+BEGIN_SRC scheme
(null? 0)
#+END_SRC

#+RESULTS:
: #f

#+BEGIN_SRC scheme
(null? "")
#+END_SRC

#+RESULTS:
: #f

** car
Get the first item in the list

#+BEGIN_SRC scheme
(car '(a b c d))
#+END_SRC

#+RESULTS:
: a

#+BEGIN_SRC scheme
(car '((hello dog) ((Yup this is cool)) 5 o e))
#+END_SRC

#+RESULTS:
: (hello dog)

#+BEGIN_SRC scheme
(car (quote (a b c d)))
#+END_SRC

#+RESULTS:
: a

Car is only defined for non-empty lists.
#+BEGIN_SRC scheme
(car '())
#+END_SRC

#+RESULTS:
: "An error occurred."

** cdr

cdr is pronounced "could-er".  cdr is the list without the first item.

#+BEGIN_SRC scheme
(cdr '(a b c d))
#+END_SRC

#+RESULTS:
: (b c d)

#+BEGIN_SRC scheme
(cdr '(((vegan hot dog)) bc d (5 4 3)))
#+END_SRC

#+RESULTS:
: (bc d (5 4 3))

#+BEGIN_SRC scheme
(cdr (quote (a b c d)))
#+END_SRC

#+RESULTS:
: (b c d)

cdr is defined for non-empty lists.
#+BEGIN_SRC scheme
(cdr '())
#+END_SRC

#+RESULTS:
: "An error occurred."

** eq?

eq? takes two arguments and each must be a non-numeric atom or a list.

#+BEGIN_SRC scheme
(eq? 5 5)
#+END_SRC

#+RESULTS:
: #t

#+BEGIN_SRC scheme
(eq? (car (quote (a b c))) (quote a))
#+END_SRC

#+RESULTS:
: #t

The above can be written like
#+BEGIN_SRC scheme
(eq? (car '(a b c)) 'a)
#+END_SRC

#+RESULTS:
: #t

#+BEGIN_SRC scheme
(eq? (cdr '(a b c d)) '(b c d))
#+END_SRC

#+RESULTS:
: #t

** lat?


lat? asks is the list is made up of only atoms.  Guile doesn't have it apparently.

#+NAME: lat
#+BEGIN_SRC scheme :noweb yes
<<atom>>
  (define lat?
    (lambda (l)
      (cond
       ;; is l '() ?
       ((null? l) #t)
       ;; is the first item in the list an atom?
       ((atom? (car l) (lat? (cdr l))))
       ;; if (car l) is not an item, then return false.
       (else #f))))
#+END_SRC

#+RESULTS: lat
: #<unspecified>

#+BEGIN_SRC scheme
  <<lat>>
  (display (lat? '(a b c d e)))
#+END_SRC

#+RESULTS:

** The cons constructor

cons stands for constructor.  It constructs lists.
This first example is an improper list.  Operations like map and filter will not work on them.
#+BEGIN_SRC scheme
(cons '1 '2)
#+END_SRC

#+RESULTS:
: (1 . 2)

#+BEGIN_SRC scheme
(cons '1 (cons '2 '()))
#+END_SRC

#+RESULTS:
: (1 2)

#+BEGIN_SRC scheme
(cons '1 (cons '2 (cons '3 (cons '4 (cons '5 '())))))
#+END_SRC

#+RESULTS:
: (1 2 3 4 5)

You can also just use list, which is much easier.

#+BEGIN_SRC scheme
(list 1 2 3 4 5)
#+END_SRC

#+RESULTS:
: (1 2 3 4 5)

** (read-answer) is a cool way to get user input
** defines/cond

Let's define an abs function or absolute value function

#+BEGIN_SRC scheme
  (define (abs x)
    (cond
     ((> x 0) x)
     ((< x 0) (- x))
     ((= x 0) 0)))
#+END_SRC

There is a simpler solution though.  If x is greater than 0, return x.  Otherwise return -x.

#+BEGIN_SRC scheme
  (define (abs x)
    (cond
     ((> x 0) x)
     (else (- x))))
#+END_SRC
** no for loops?  let
Scheme does not provide a for loop.  Instead it forces you to write recursive functions (which normally look better than for loops).  Most schemes then compile/interpret those recursive calls into for loops internally anyway.  This is called tail call optimization.

#+BEGIN_SRC scheme
  (define (print1-10 x)
    (unless (= x 11)
      (display x)
      (display " ")
      (print1-10 (+ x 1))))

(print1-10 1)
#+END_SRC

This can be done a little better though.  You can used a named let.  It names a function and then calls it.

#+BEGIN_SRC scheme
  (let loop ((x 1))
    (unless (= x 11)
      (display x) (display " ")
      (loop (+ 1 x))))
#+END_SRC

This is the same as
#+BEGIN_SRC scheme
  (define loop (lambda (x 1)
                 (unless (= x 11)
                   (display x)
                   (display " ")
                   (loop (+ 1 x)))))

  (loop)
#+END_SRC
** wait [] are the same as ()?

Apparently, scheme treats [] the same as ().

This can be useful in let expressions to make them easier to read.

#+BEGIN_SRC scheme
(let ([n 5] [b 4]) (+ n b))
#+END_SRC

#+RESULTS:
: 9

Check this out, you can store procedures in a let variable:

#+BEGIN_SRC scheme
(let ([a +]) (a 1 2 3))
#+END_SRC

#+RESULTS:
: 6

** lambdas
Scheme functions are called procedures, because scheme is based on lambda calculus.  Often times procedures are created using a lambda expression.


#+BEGIN_SRC scheme
  (lambda (x y z)
    (+ x y z))
#+END_SRC

Here is what is really cool!  You can create a lambda function and immediately pass it arguments.  This is like an anonymous function in javascript.

#+BEGIN_SRC scheme
  ((lambda (x y z)
     (+ x y z))
   1 2 3)
#+END_SRC

#+RESULTS:
: 6

** create non-global variables let again
#+BEGIN_SRC scheme
(let ((a 1) (b 2)) (+ a b))
#+END_SRC

** what's let* ?

(let* binds the variable values sequentially.

Suppose you have a let like so:

#+BEGIN_SRC scheme
  (let ((a 1) (b (+ 1 a))) (+ a b))
#+END_SRC

#+RESULTS:
: "An error occurred."

The error occurs because scheme tries to define both a & b at the same time!
This won't work, because b can only be defined after a has a value.  So instead,
you must use let*


#+BEGIN_SRC scheme
  (let* ((a 1) (b (+ 1 a))) (+ a b))
#+END_SRC

#+RESULTS:
: 3

** What's letrec ?
#+BEGIN_SRC scheme
  (letrec ((even? (lambda (n)
                    (if (zero? n)
                        #t
                        (odd? (- n 1)))))
           (odd? (lambda (n)
                   (if (zero? n)
                       #f
                       (even? (- n 1))))))
    (even? 88))

#+END_SRC

** closures
A closure is an environment with the local variables and a reference to the higher environment, which contains a reference to all of the higher environments' variables.  One create a new sub-environment, when one uses a lambda.  The previous environment is saved between calls.  This is called a closure.

#+BEGIN_SRC scheme
  (define make-counter ()
    (let ((current-number 0))
      (lambda ()
        (set! current-number (+ current-number 1))
        current-number)))
  (define number-generator (make-counter))
#+END_SRC

Each call to number-generator, will display an increasing number...

A better example is:
#+BEGIN_SRC scheme
  (let loop ((x i))
    (display x)
    (loop (1+ x)))
#+END_SRC
** date types
*** Vectors
#+BEGIN_SRC scheme
#(1 2 3)
#+END_SRC

#+RESULTS:
: #(1 2 3)
*** lists
A list is built up of cons:
#+BEGIN_SRC scheme
(cons 1 (cons 2 (cons 3 (cons 4 '()))))
#+END_SRC

#+RESULTS:
: (1 2 3 4)

#+BEGIN_SRC scheme
   (list 1 2 3 4 5 6 7 8)
#+END_SRC

#+RESULTS:
: (1 2 3 4 5 6 7 8)

This is in improper list
#+BEGIN_SRC scheme
(cons 1 (cons 2 (cons 3 4)))
#+END_SRC

#+RESULTS:
: (1 2 3 . 4)

*** pairs
#+BEGIN_SRC scheme
(cons 1 2)
#+END_SRC

#+RESULTS:
: (1 . 2)

** Scheme conventions
A function ending in "?" returns a boolean value.
A function ending in "!" is a function or a macro with side effects.
** conditionals
*** if
(if TEST THEN ELSE)

#+BEGIN_SRC scheme
(if (= 5 5) #t #f)
#+END_SRC

#+RESULTS:
: #t

The coolest if I've seen.
#+BEGIN_SRC scheme
((if #f + *) 3 4)
#+END_SRC
*** cond

(cond <clause1> <clause2> ...)

Each clause looks like
(<test> <expression1> <expression2> ...)

#+BEGIN_SRC scheme :hlines yes
  (cond
   ((< 4 1) #f)
   ((= 6 7) #f)
   (else #t))
#+END_SRC

#+RESULTS:
: #t

Clauses can also be written as
(test => <expression>)
#+BEGIN_SRC scheme :hlines yes
  (cond
   ((< 4 1) => #f)
   ((= 6 7) => #f)
   (else #t))
#+END_SRC

#+RESULTS:
: "An error occurred."
*** case
(case <key> <clause1> <clause2> ...)

Each clause looks like:
((<datum1> <datum2> ...) <expression1> <expression2> ...)

The last clause can look like
(else <expression1> <expression2>)

#+BEGIN_SRC scheme
  (case (* 2 3)
    ((2 3 5 7) 'prime)
    ((1 4 6 8) 'composite)
    (else 'whoKnows))
#+END_SRC

#+RESULTS:
: composite
** begin
Sequentially evaluate all the expressions left to right, and return the last result.
(begin <expression1> <expression2> ...)
** keywords
Suppose I have a function that has 10 optional arguments.  It would be silly to force the user of the function
remember each argument.  Instead the person can use keywords. ie:

These two function calls are the same:

#+BEGIN_SRC scheme
(make-window #:width 800 #:height 100 #:color green #:font Arial)
(make-window #:height 100 #:width 800  #:font Arial #:color green)
#+END_SRC
* POSIX stuff
[[info:guile#POSIX][info:guile#POSIX]]
* Things I should try to understand
** let, letrec, let*
create a local environment with local variables or definitions
#+BEGIN_SRC scheme
  (let ((x 5))
    (define (someFunc y) (+ 5 y))
    (someFunc x))
#+END_SRC

#+RESULTS:
: 10

** delay and force
This is how promises are made...
(delay <expression>) returns a promise, which can be called by (force) to evaluate <expression.
** eval
** ports
*** (call-with-input-file)
*** (call-with-output-file)
** call-with-current-continuation
** how to debug guile code
* Working with the Repel
In a terminal type "guile".  This opens a guile repel, where you can run arbitrary guile code.  Try this

,optimize (+ 2 (+ 3 2 ) 1)

You should see the resulting code become 8.  This means that the guile optimizer would simple turn =(+ 2 (+ 3 2) 1) into 8, when it compiles the program.  This is one example of how guile makes code run faster.

~,x functionName~ will show you the bytecode of your code.
* Learn about Scheme online
http://ds26gte.github.io/tyscheme/index.html
http://www.schemers.org/
https://mitpress.mit.edu/sicp/sicp.html
* guile getopt

Some of your guile scripts may accept arguments.  Guile has a command that helps you parse those arguments.  To use this facility, include this near the top of your file.

#+BEGIN_SRC scheme
(use-modules ice-9 getopt-long)
#+END_SRC
* online resources
How to design programs
http://www.htdp.org/2003-09-26/Book/curriculum-Z-H-1.html#node_toc_start

The Scheme Programming Language
http://www.scheme.com/tspl3/

Structure and Interpretation of Computer Programs
https://mitpress.mit.edu/sicp/full-text/book/book.html

* I can import guile modules like this:

#+BEGIN_SRC scheme
  (use-modules (srfi srfi-19))

  (display (date->string (current-date)
                         "~H:~S"))
  (newline)

#+END_SRC

#+RESULTS:

Maybe I should implement more srfi modules for guile.
* file stuff
** get the current directory
#+BEGIN_SRC scheme
(getcwd)
#+END_SRC

#+RESULTS:
: "An error occurred."
** change the current directory
#+BEGIN_SRC scheme
(chdir)
#+END_SRC
* web modules

(use-modules (web uri))

(uri->string (build-uri 'https #:host "www.gnu.org"))
** web client  ???
 Guile comes with a web client!  This is like a headless firefox.  It's actually like curl!

So here's an example:

#+BEGIN_SRC scheme
(http-get (string->uri "http://localhost/html/oops.html"))
#+END_SRC

#+RESULTS:
: "An error occurred."

This does a get request on that uri!  How cool is that!  I can use guile to do GET, PUT, POST, etc.
** to build a web application I need to use the response function

The way the Web works, is my web server gets a web request.  Then my web server sends a web response.  So my handler needs to build web responses, via build-response.
* security considerations
https://savannah.gnu.org/forum/forum.php?forum_id=8705

Modern operating systems cannot guarantee that GETs and POSTs to localhost, come from localhost.  AKA if you are running a server on localhost, you have to assume that anyone on the internet can run queries against it.  Use named pipes or unix sockets to ensure only local execution only.
* cool things to play with guile
https://libfive.com/studio/
https://dthompson.us/projects/chickadee.html
* writing a guile test to prove that I know guile
** How would you write a function to include an optional argument with keyword "extra"?

:Answer:
#+BEGIN_SRC scheme
  (define* (silly #:extra)
    (when extra
      #t)
    #f)
#+END_SRC
:END:
** What does the following return?

#+BEGIN_SRC scheme
  (define* (cool #:key more)
    (when more
      #t
      #f))

  (display (cool #:more #t))
#+END_SRC


:answer:
#f
:END:
** How do you specify the default value for a key in a define* ?

:answer:
#+BEGIN_SRC scheme
    (define* (awesome #:key (more 5))
      more)

  (display (awesome))
  (display (awesome #:more 3))
#+END_SRC

#+RESULTS:
: 53
:END:
** write a named let to print the numbers 1-10
:answer:
#+BEGIN_SRC scheme
  (let loop ((i 1))
    (when (< i 11)
      (display i)
      (display " ")
      (loop (+ i 1))))
  (display "\n")
#+END_SRC

#+RESULTS:

:END:
** What does the following code produce?

#+BEGIN_SRC guile
(+ 1 #| 1 |# 2)
#+END_SRC

:answer:
3

guile apparently supports a nested comment!  Weird right?

#|  is the beginning on the commend and #| is the end.

#+BEGIN_SRC guile
(+ 1 #| 1 |# 2)
#+END_SRC

#:RESULTS
3
:END:
** How can you test if you can read and write a file?

:answer:
The access? (path how) procedure.

#+BEGIN_SRC guile
(access? "~/Downloads/autotools.pdf" 'R_OK)
(access? "~/Downloads/autotools.pdf" 'W_OK)

;; or

(access? "~/Downloads/autotools.pdf" (logior 'R_OK 'W_OK))

;; the other ones are X_OK (execute) and F_OK (file exists).
#+END_SRC
:END:

** write a program to open a file in tmp and write "Hello World!"

:answer:
#+BEGIN_SRC scheme
  (use-modules (ice-9 textual-ports))

  (let ((port (open-output-file "/tmp/file.txt")))
    (put-string port "Hello World!\n")
    (force-output port))
#+END_SRC

#+RESULTS:
: #<unspecified>

#+BEGIN_SRC sh :results output :exports both
cat /tmp/file.txt
#+END_SRC

#+RESULTS:
: Hello World!

:END:
** what's the difference between let, letrec, let*, letrec*

:answer:
let* bindings are performed sequentially.  So one variable can be defined in terms of the previous ones

#+BEGIN_SRC scheme
  (let* ((a 2) (b (+ a 1)) (c (+ a b)))
   ;;code here
    )

#+END_SRC

letrec will let you define a variable with a lambda

#+BEGIN_SRC scheme
  (letrec ((a (lambda () (+ 5 7))))
    ;; code
    )



#+END_SRC

letrec* will let you define a variable with a lambda and it defines all of the variables sequentially.

#+BEGIN_SRC scheme
  (letrec* ((a (lambda ()
                 (+ 5 3)))
            (b (lambda ()
                 (+ 8 a))))
    ;; code here
    )
#+END_SRC

:END:
** what guile module lets you read from stdin?

:answer:
#+BEGIN_SRC scheme
(use-module (ice-9 readline))
#+END_SRC
:END:
** what guile module lets you do pattern matching?
:answer:
(use-module (ice-9 match))
:END:

** how does guile represent a vector?  What does it look like when you print it?

:answer:
#(1 2 3 4)
:END:

** What is an alist?

:ANSWER:
An alist is an association list.  It is a list of key and value pairs.

Alist  =  '( (car . cdr) (key . value) ...)
:END:
** How do you add an a pair to the association list?

:ANSWER:
acons

(set! task-list (acons 3 "pay gas bill"))

The problem with acons is that it will let you have multiple
key -> value pairs, where key are not guaranteed to be unique.

If you want unique keys, then one should use assq-set!, assv-set!, and assoc-set!
:END:

** write some guile macros
** what is a continuation?
:answer:
A continuation is the code that is run after a given function or expression is returned.
:END:
** consider the following snippet of code

#+BEGIN_SRC scheme
  (define (silly)
    (bar)
    (+ 5 2)
    (- 4 1))
#+END_SRC

what is the continuation after (bar) is run?

:answer:
(+ 5 2)
(- 4 1)
:END:
** what does latent typing mean?

:answer:
Latent typing means that there is no way to determine that a variable in scheme will ALWAYS be of a certain type.

It's type may change during execution.
:END:
* guild lint file.scm to lint guile source code!
* decoding values from POST requests
https://stackoverflow.com/questions/46656074/how-to-read-post-data-in-the-guile-web-server

https://git.sr.ht/~amz3/guile-gotofish/tree/master/web/decode.scm

https://git.sr.ht/~amz3/guile-gotofish/tree

This is the guy who made the above code: amirouche@hyper.dev

it is currently licensed under the GPL, but guile is LGPL...
